package com.ruoyi.accounts.tcp;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.accounts.domain.EmpWinLog;
import com.ruoyi.accounts.mapper.EmpPropertyMapper;
import com.ruoyi.accounts.service.IEmpPropertyService;
import com.ruoyi.accounts.service.IEmpWinLogService;
import com.ruoyi.common.core.domain.machine.EmpClawVo;
import com.ruoyi.framework.struct.JavaStruct;
import com.ruoyi.framework.struct.StructException;
import com.ruoyi.store.mapper.EmpGoodMapper;
import com.ruoyi.store.service.IEmpGameLogService;
import com.ruoyi.store.service.IEmpKnapsackService;
import lombok.var;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.ruoyi.accounts.aop.CheckSocketConnection;

import javax.annotation.Resource;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.ruoyi.accounts.service.ITicketService;

@Service
public class TcpThreadService {

    private static final Logger log = LoggerFactory.getLogger(TcpThreadService.class);

    private final ExecutorService executorService;

    @Autowired
    public TcpThreadService(@Qualifier("fixedThreadPool") ExecutorService executorService) {
        this.executorService = executorService;
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private GameInfoService gameInfoService;
    @Resource
    private IEmpPropertyService empPropertyService;
    @Resource
    private IEmpGameLogService empGameLogService;
    @Resource
    private IEmpKnapsackService empKnapsackService;
    @Autowired
    private IEmpWinLogService empWinLogService;
    @Autowired
    EmpPropertyMapper empPropertyMapper;
    @Autowired
    EmpGoodMapper empGoodMapper;
    @Autowired
    private ITicketService ticketService;

    @Scheduled(cron = "0/20 * * * * ?")
    public void checkHeartBeat() {
        log.info("现在开始移除超时连接");
        //TcpUsersStruct.removeTimeout();
    }

    public void handleClient(Socket clientSocket) {
        executorService.submit(() -> {
            try {
                DataOutputStream output = new DataOutputStream(clientSocket.getOutputStream());
                DataInputStream input = new DataInputStream(clientSocket.getInputStream());

                while (!clientSocket.isClosed()) {

                    byte[] buffer = new byte[TcpConstant.MESSAGE_LENGTH];
                    input.readFully(buffer);
                    log.info("客户端消息查长度:" + buffer.length);

                    TcpMsgStruct4 request = new TcpMsgStruct4();
                    JavaStruct.unpack(request, buffer, ByteOrder.LITTLE_ENDIAN);
                    log.error("==========================");
                    log.error("==========================");
                    log.error("==========================");
                    log.info("客户端消息:");
                    log.info("msgid=" + request.msgid);
                    log.info("uid to string=" + StringUtils.removeNullBytesAndToString(request.uid));
                    log.info("param to string=" + StringUtils.removeNullBytesAndToString(request.param));
                    log.error("==========================");
                    log.error("==========================");
                    log.error("==========================");
                    int msgid = request.msgid;
                    String uid = StringUtils.removeNullBytesAndToString(request.uid);
                    String param = StringUtils.removeNullBytesAndToString(request.param);

                    if (16000 == msgid) {
                        //保存登录信息
                        //1.登录验证 LoginDev,msgid定义为16000，uid为设备ID，扩展数据无
                        //2.登录返回 LoginRet,msgid定义为16001, uid为设备ID，扩展数据int类型，errorid：0为正常登录，-1为改设备已经登录，后期扩展其他错误类型
                        TcpUsersStruct.put(uid, clientSocket);
                        TcpMsgStruct4 response = new TcpMsgStruct4();
                        response.msgid = 16001;
                        response.uid = TcpMsgStruct4Util.packUid(uid);
                        response.param = new byte[296];
                        response.param[0] = 1;

                        byte[] pack = JavaStruct.pack(response, ByteOrder.LITTLE_ENDIAN);
                        log.info("登录成功");
                        output.write(pack);
                        output.flush();
                    } else if (16200 == msgid) {
                        //心跳
                        //10.DevPing,msgid定义16200，uid为该设备当前占用玩家ID，如果空闲为0，扩展无
                        if (!TcpUsersStruct.exists(uid)) {
                            byte[] pack = getMsg(1, "", new byte[]{1});
                            output.write(pack);
                            output.flush();
                        }
                        TcpUsersStruct.updateHeartbeat(uid);

                        byte[] pack = getMsg(1, "", new byte[]{0});
                        output.write(pack);
                        output.flush();
                    } else if (16011 == msgid) {
                        //  投币成功，返回:msgid定义为16011，uid为玩家ID，扩展数据int类型，0位操作成功，-1为操作失败
                        try {
                            //修改游戏状态为可玩
                            if (request.param[0] == 0) {
                                var rec = stringRedisTemplate.opsForValue().get(uid);
                                if (rec == null) {
                                    // 投币应答超时
                                    continue;
                                }
                                ObjectMapper objectMapper = new ObjectMapper();
                                JsonNode jsonNode = objectMapper.readTree(rec);
                                String machineID = jsonNode.get("machineID").asText();
                                // 获取机器类型
                                Long machineTypeId = gameInfoService.getMachineTypeFromMachine(machineID);
                                int machineTypeIdInt = 1;
                                if (machineTypeId == null) {
                                    log.info("找不到ID为" + machineID + "的机器类型，提前返回");
                                    GameStateService.sendLiveData(uid, "找不到ID为" + machineID + "的机器类型,投币失败！", null, false);
                                    continue;
                                } else {
                                    machineTypeIdInt = machineTypeId.intValue();
                                }
                                GameStateService.setGameState(uid, GameStateEnum.Playing);
                                switch (machineTypeIdInt) {
                                    case 2:
                                        //推币机 
                                        break;
                                    case 3:
                                        //彩票机
                                        break;
                                    case 4:
                                        //打怪机
                                        break;
                                    default:
                                        // 抓娃娃
                                        var machine = empPropertyMapper.getByEquipmentID(machineID);
                                        var delay = 20;
                                        log.info(objectMapper.writeValueAsString(machine));
                                        if (machine != null && machine.getOccupyTime() != null) {
                                            delay = machine.getCustodyTime();
                                        }

                                        // GameStateService.setGameState(uid, GameStateEnum.Playing);
                                        /// 开始一个下抓倒计时
                                        log.info("投币成功，" + delay + "秒后自动下抓");
                                        Runnable task = () -> {
                                            log.info("定时下抓执行");
                                            var pack = getMsg(16014, uid, new byte[296]);
                                            sendMessage(clientSocket, pack);
                                            GameStateService.sendLiveData(uid, "超时", null);
                                        };

                                        GameStateService.scheduleTask(uid, task, delay);
                                        break;
                                }
                                // 扣除币
                                Long storeID = jsonNode.get("storeID").asLong();
                                Long coins = jsonNode.get("coins").asLong();
                                var empClawVo = new EmpClawVo();

                                empClawVo.setStoreID(storeID);
                                empClawVo.setCustomID(uid);
                                empClawVo.setCoins5G(coins);

                                empPropertyService.playGame(empClawVo);
                                GameStateService.sendLiveData(uid, "投币成功", null);
                            }
                        } catch (Exception e) {
                            log.error("==========================");
                            log.error("==========================");
                            log.error("==========================");
                            log.error("投币返回错误", e.getMessage(), e.getStackTrace());

                            log.error("==========================");
                            log.error("==========================");
                            log.error("==========================");
                        }

                    } else if (16016 == msgid) {
                        // 结算
                        //板子反馈光眼信号，抓到娃娃
                        // 9.GrabRtn,msgid定义16016,uid为玩家ID，扩展数据int类型，1表示抓取成功，-1为操作失败
                        try {
                            var rec = stringRedisTemplate.opsForValue().get(uid);
                            if (rec == null) {
                                GameStateService.removeGameState(uid);
                                continue;
                            }
                            
                            ObjectMapper objectMapper = new ObjectMapper();
                            JsonNode jsonNode = objectMapper.readTree(rec);
                            Long storeID = jsonNode.get("storeID").asLong();
                            Long coins = jsonNode.get("coins").asLong();
                            //Long machineID = jsonNode.get("machineID").asLong();
                            var goodIDL = jsonNode.get("goodID").asLong();
                            var goodID = empGoodMapper.selectByID(goodIDL);
                            String machineID = jsonNode.get("machineID").asText();
                            var machine = empPropertyMapper.getByEquipmentID(machineID);
                            // 获取机器类型
                            Long machineTypeId = gameInfoService.getMachineTypeFromMachine(machineID);
                            int machineTypeIdInt = 1;
                            if (machineTypeId == null) {
                                log.info("找不到ID为" + machineID + "的机器类型，提前返回");
                                GameStateService.sendLiveData(uid, "找不到ID为" + machineID + "的机器类型,投币失败！", null, false);
                                continue;
                            } else {
                                machineTypeIdInt = machineTypeId.intValue();
                            }
                            switch (machineTypeIdInt) {
                                case 2:
                                    //推币机
                                    if (request.param[0] == 0x2d) {
                                        // 没中奖
                                        GameStateService.sendLiveData(uid, "未中奖", null,false);
                                        break;
                                    } else {
                                        // 中奖
                                        GameStateService.sendLiveData(uid, "中奖", null,true);
                                        break;
                                    }
                                case 3:
                                    //彩票机
                                    break;
                                case 4:
                                    //打怪机
                                    break;
                                default:
                                    // 抓娃娃
                                    stringRedisTemplate.delete(uid);
                                    
                                    EmpClawVo empClawVo = new EmpClawVo();
                                    empClawVo.setCustomID(uid);
                                    empClawVo.setCreateTime(new Date());
                                    empClawVo.setStoreID(storeID);
                                    empClawVo.setCoins5G(coins);
                                    empClawVo.setMachineID(machine.getMachineID());

                                    // 清除所有游戏状态
                                    GameStateService.removeGameState(uid);

                                    if (request.param[0] == 0x2d) {
                                        // 没中奖
                                        // 异常处理
                                        empClawVo.setStatus(0);
                                        empGameLogService.recordGameLogs(empClawVo);
                                        var failCountSrt = stringRedisTemplate.opsForValue().get(uid + "_failCount");
                                        if (failCountSrt == null) {
                                            stringRedisTemplate.opsForValue().set(uid + "_failCount", "1", 1, TimeUnit.HOURS);
                                            continue;
                                        }
                                        // 如果没抓中，累计次数。次数达到，给奖励
                                        var failCount = Integer.parseInt(failCountSrt);
                                        failCount++;

                                        var maxFailCount = 10;
                                        if (machine != null && machine.getFailCount() != null) {
                                            maxFailCount = machine.getFailCount();
                                        }

                                        if (failCount > maxFailCount) {
                                            empKnapsackService.addGood(uid, goodID);
                                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                            String currentDateTime = sdf.format(new Date());
                                            EmpWinLog empWinLog = new EmpWinLog();
                                            empWinLog.setCreatedTime(currentDateTime);
                                            empWinLog.setCustomID(uid);
                                            empWinLog.setGoodID(goodID);
                                            empWinLogService.insertEmpWinLog(empWinLog);
                                            stringRedisTemplate.delete(uid + "_failCount");
                                            GameStateService.sendLiveData(uid, "安慰奖", null);
                                        } else
                                            stringRedisTemplate.opsForValue().set(uid + "_failCount", String.valueOf(failCount), machine.getFailCountTime(), TimeUnit.MINUTES);
                                        GameStateService.sendLiveData(uid, "未抓中", null);
                                    } else {
                                        var failCountSrt = stringRedisTemplate.opsForValue().get(uid + "_failCount");
                                        if (failCountSrt == null) {
                                            stringRedisTemplate.delete(uid + "_failCount");
                                        }

                                        empClawVo.setStatus(1);
                                        empGameLogService.recordGameLogs(empClawVo);
                                        // 发送消息给前端
                                        GameStateService.boardcast(uid);
                                        // 放到背包
                                        empKnapsackService.addGood(uid, goodID);
                                        EmpWinLog empWinLog = new EmpWinLog();

                                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                        String currentDateTime = sdf.format(new Date());

                                        empWinLog.setCreatedTime(currentDateTime);
                                        empWinLog.setCustomID(uid);
                                        empWinLog.setGoodID(goodID);
                                        empWinLogService.insertEmpWinLog(empWinLog);

                                        GameStateService.sendLiveData(uid, "已抓中", null);
                                    }
                                    break;
                            }
                        } catch (Exception e) {
                            log.error("==========================");
                            log.error("==========================");
                            log.error("==========================");

                            log.error("结算错误", e.getMessage(), e.getStackTrace());

                            log.error("==========================");
                            log.error("==========================");
                            log.error("==========================");
                        }
                    } else if (16020 == msgid) {
                        //获得5G彩票
                        process5GTicket(uid, request.param);
                    } else if (16013 == msgid) {
                        //发送退票16012后接收16013确认修改5G彩票
                        process5GTicket(uid, request.param);
                    }
                }
            } catch (Exception e) {
                // 处理与客户端通信时发生的异常
                log.error("tcp错误:" + ExceptionUtil.stacktraceToString(e));
            }
        });
    }

    public Future<String> sendMessage(Socket clientSocket, byte[] pack) {
        Future<String> future = executorService.submit(() -> {
            try {
                OutputStream outputStream = clientSocket.getOutputStream();
                DataOutputStream output = new DataOutputStream(outputStream);

                output.write(pack);
                output.flush();
            } catch (Exception e) {
                log.error("sendMessage异常:" + ExceptionUtil.stacktraceToString(e));
                throw new RuntimeException(e.getMessage());
            }
            return "";
        });

        return future;
    }

    public byte[] getMsg(int msgid, String uid, byte[] param) {
        log.info("消息： " + msgid + "  " + uid + "  ");
        TcpMsgStruct4 response = new TcpMsgStruct4();
        response.msgid = msgid;
        response.uid = TcpMsgStruct4Util.packUid(uid);
        response.param = param;
        byte[] pack = null;
        try {
            pack = JavaStruct.pack(response, ByteOrder.LITTLE_ENDIAN);
        } catch (StructException e) {
            throw new RuntimeException(e);
        }
        return pack;
    }

    // 模拟投币返回消息
    public void SimStarBack(String uid, Socket clientSocket) {
        try {
            // 投币成功，修改游戏状态为可玩

            var rec = stringRedisTemplate.opsForValue().get(uid);
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(rec);
            String machineID = jsonNode.get("machineID").asText();
            var machine = empPropertyMapper.getByEquipmentID(machineID);
            var delay = 20;
            log.info(objectMapper.writeValueAsString(machine));
            if (machine != null && machine.getOccupyTime() != null) {
                delay = machine.getCustodyTime();
            }

            GameStateService.setGameState(uid, GameStateEnum.Playing);
            /// 开始一个下抓倒计时
            log.info("投币成功，" + delay + "秒后自动下抓");
            Runnable task = () -> {
                log.info("定时下抓执行");
                var pack = getMsg(16014, uid, new byte[296]);
                sendMessage(clientSocket, pack);
                GameStateService.sendLiveData(uid, "超时", null);

                try {
                    Thread.sleep(500);
                } catch (InterruptedException ignored) {

                }
                SimPlayBack(uid);
            };

            GameStateService.scheduleTask(uid, task, delay);
            // 扣除币

            Long storeID = jsonNode.get("storeID").asLong();
            Long coins = jsonNode.get("coins").asLong();
            var empClawVo = new EmpClawVo();

            empClawVo.setStoreID(storeID);
            empClawVo.setCustomID(uid);
            empClawVo.setCoins5G(coins);

            empPropertyService.playGame(empClawVo);
            GameStateService.sendLiveData(uid, "投币成功", null);

        } catch (Exception e) {
            log.error("==========================");
            log.error("==========================");
            log.error("==========================");
            log.error("投币返回错误", e.getMessage(), e.getStackTrace());

            log.error("==========================");
            log.error("==========================");
            log.error("==========================");
        }
    }

    public static boolean percentChance() {
        Random random = new Random();
        return random.nextInt(100) < 30; // 生成0到99之间的随机数，30%的概率小于30
    }

    public void SimPlayBack(String uid) {
        try {
            var rec = stringRedisTemplate.opsForValue().get(uid);
            if (rec == null) {
                GameStateService.removeGameState(uid);
                return;
            }
            stringRedisTemplate.delete(uid);

            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(rec);
            Long storeID = jsonNode.get("storeID").asLong();
            Long coins = jsonNode.get("coins").asLong();
            //Long machineID = jsonNode.get("machineID").asLong();
            var goodIDL = jsonNode.get("goodID").asLong();
            var goodID = empGoodMapper.selectByID(goodIDL);
            String machineID = jsonNode.get("machineID").asText();
            var machine = empPropertyMapper.getByEquipmentID(machineID);

            EmpClawVo empClawVo = new EmpClawVo();
            empClawVo.setCustomID(uid);
            empClawVo.setCreateTime(new Date());
            empClawVo.setStoreID(storeID);
            empClawVo.setCoins5G(coins);
            empClawVo.setMachineID(machine.getMachineID());

            // 清除所有游戏状态
            GameStateService.removeGameState(uid);

            if (percentChance()) {
                // 没中奖
                // 异常处理
                empClawVo.setStatus(0);
                empGameLogService.recordGameLogs(empClawVo);
                var failCountSrt = stringRedisTemplate.opsForValue().get(uid + "_failCount");
                if (failCountSrt == null) {
                    stringRedisTemplate.opsForValue().set(uid + "_failCount", "1", 1, TimeUnit.HOURS);
                    return;
                }
                // 如果没抓中，累计次数。次数达到，给奖励
                var failCount = Integer.parseInt(failCountSrt);
                failCount++;

                var maxFailCount = 10;
                if (machine != null && machine.getFailCount() != null) {
                    maxFailCount = machine.getFailCount();
                }

                if (failCount > maxFailCount) {
                    empKnapsackService.addGood(uid, goodID);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String currentDateTime = sdf.format(new Date());
                    EmpWinLog empWinLog = new EmpWinLog();
                    empWinLog.setCreatedTime(currentDateTime);
                    empWinLog.setCustomID(uid);
                    empWinLog.setGoodID(goodID);
                    empWinLogService.insertEmpWinLog(empWinLog);
                    stringRedisTemplate.delete(uid + "_failCount");
                    GameStateService.sendLiveData(uid, "安慰奖", null);
                } else
                    stringRedisTemplate.opsForValue().set(uid + "_failCount", String.valueOf(failCount), machine.getFailCountTime(), TimeUnit.MINUTES);
                GameStateService.sendLiveData(uid, "未抓中", null);
            } else {
                var failCountSrt = stringRedisTemplate.opsForValue().get(uid + "_failCount");
                if (failCountSrt == null) {
                    stringRedisTemplate.delete(uid + "_failCount");
                }

                empClawVo.setStatus(1);
                empGameLogService.recordGameLogs(empClawVo);
                // 发送消息给前端
                GameStateService.boardcast(uid);
                // 放到背包
                empKnapsackService.addGood(uid, goodID);
                EmpWinLog empWinLog = new EmpWinLog();

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String currentDateTime = sdf.format(new Date());

                empWinLog.setCreatedTime(currentDateTime);
                empWinLog.setCustomID(uid);
                empWinLog.setGoodID(goodID);
                empWinLogService.insertEmpWinLog(empWinLog);

                GameStateService.sendLiveData(uid, "已抓中", null);
            }
        } catch (Exception e) {
            log.error("==========================");
            log.error("==========================");
            log.error("==========================");
            log.error("结算错误", e.getMessage(), e.getStackTrace());
            log.error("==========================");
            log.error("==========================");
            log.error("==========================");
        }
    }

    /// 发送投币消息
    @CheckSocketConnection
    public void SendStart(String user, String uid, int coin) throws ExecutionException, InterruptedException {
        log.info("发送投币消息");
        byte[] byteArray = new byte[296];
        byteArray[0] = (byte) coin;
        var pack = getMsg(16010, user, byteArray);
        sendMessage(TcpUsersStruct.get(uid), pack).get();

        Thread.sleep(500);
        SimStarBack(user, TcpUsersStruct.get(uid));
    }

    // 单独发送投币消息给机器
    @CheckSocketConnection
    public void SendPutCoinToMachine(String user, String uid, int coin) throws ExecutionException, InterruptedException {
        log.info("发送投币消息");
        byte[] byteArray = new byte[296];
        byteArray[0] = (byte) coin;
        var pack = getMsg(16010, user, byteArray);
        sendMessage(TcpUsersStruct.get(uid), pack).get();
    }

    // 单独发送雨刮消息给机器
    @CheckSocketConnection
    public void SendWiperToMachine(String user, String uid) throws ExecutionException, InterruptedException {
        log.info("发送雨刮消息");
        byte[] byteArray = new byte[296];
        var pack = getMsg(16018, user, byteArray);
        sendMessage(TcpUsersStruct.get(uid), pack).get();
    }

    /// 发送上消息
    @CheckSocketConnection
    public void SendUp(String user, String uid) throws ExecutionException, InterruptedException {
        var pack = getMsg(16002, user, new byte[296]);
        sendMessage(TcpUsersStruct.get(uid), pack).get();
    }

    /// 发送下消息
    @CheckSocketConnection
    public void SendDown(String user, String uid) throws ExecutionException, InterruptedException {
        var pack = getMsg(16004, user, new byte[296]);
        sendMessage(TcpUsersStruct.get(uid), pack).get();
    }

    /// 发送左消息
    @CheckSocketConnection
    public void SendLeft(String user, String uid) throws ExecutionException, InterruptedException {
        var pack = getMsg(16006, user, new byte[296]);
        sendMessage(TcpUsersStruct.get(uid), pack).get();
    }

    /// 发送右消息
    @CheckSocketConnection
    public void SendRight(String user, String uid) throws ExecutionException, InterruptedException {
        var pack = getMsg(16008, user, new byte[296]);
        sendMessage(TcpUsersStruct.get(uid), pack).get();
    }

    /// 发送PLAY消息
    @CheckSocketConnection
    public void SendPLAY(String user, String uid) throws ExecutionException, InterruptedException {
        var pack = getMsg(16014, user, new byte[296]);
        sendMessage(TcpUsersStruct.get(uid), pack).get();

        //Thread.sleep(500);
        //SimPlayBack(user);
    }

    /// 发送退票信号
    @CheckSocketConnection
    public void SendRefund(String user, String uid) throws ExecutionException, InterruptedException {
        var pack = getMsg(16012, user, new byte[296]);
        sendMessage(TcpUsersStruct.get(uid), pack).get();
    }

    /// 处理5G彩票
    public void process5GTicket(String uid, byte[] param) {
        try {
            //param转Long，并检查是否转成功
            String paramStr = new String(param);
            int paramInt = Integer.parseInt(paramStr);
            Long paramLong = Long.parseLong(paramStr);
            
            if (paramInt != 0) {
                //在redis中获取用户ID通过机器uid
                var rec = stringRedisTemplate.opsForValue().get(uid);
                
                if (rec == null) {
                    //删除游戏状态
                    GameStateService.removeGameState(uid);
                    return;
                }
                
                //获取用户ID
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode jsonNode = objectMapper.readTree(rec);                
                String customID = jsonNode.get("customID").asText();
                
                //获取门店ID,机器ID
                Long storeID = jsonNode.get("storeID").asLong();
                
                String hardwareNumber = jsonNode.get("machineID").asText();
                
                // 获取机器类型
                Long machineId = gameInfoService.getMachineTypeFromMachine(hardwareNumber);
                
                // 开启事务，更新5G彩票 emp_custom_detail，emp_property的Ticket字段
                boolean updateSuccess = ticketService.updateTicket(customID, paramInt);
                
                // 如果事务成功，则记录日志
                if (updateSuccess) {
                    try {
                        var empClawVo = new EmpClawVo();
                        empClawVo.setCustomID(customID);
                        empClawVo.setMachineID(machineId);
                        empClawVo.setCoins5G(paramLong);
                        empClawVo.setStoreID(storeID);
                        empClawVo.setCreateTime(new Date());
                        empGameLogService.recordGameLogs(empClawVo);
                    } catch (Exception e) {
                        log.error("更新5G彩票记录日志失败", e.getMessage(), e.getStackTrace());
                    }
                } else {
                    log.error("更新5G彩票失败，用户ID: " + customID);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("处理5G彩票异常", e);
        }
    }
}